﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JGSY.DotNetty.Common
{
    public class ConsoleHelper
    {
        /// <summary>
        /// 写入控制台
        /// </summary>
        /// <param name="title">标题</param>
        /// <param name="message">消息</param>
        /// <param name="subTitle">副标题</param>
        /// <param name="consoleColor">颜色</param>
        public static void Write(string title, string message, string subTitle, ConsoleColor consoleColor)
        {
            Console.ForegroundColor = consoleColor;
            string dateNowTxt = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
            Console.Write(string.IsNullOrEmpty(subTitle) ? $"[{dateNowTxt}]{title}:{message}" : $"[{dateNowTxt}]{title}[{subTitle}]:{message}");
            Console.ForegroundColor = ConsoleColor.White;
        }
        /// <summary>
        /// 写入控制台
        /// </summary>
        /// <param name="title">标题</param>
        /// <param name="message">消息</param>
        /// <param name="subTitle">副标题</param>
        /// <param name="consoleColor">颜色</param>
        public static void WriteLine(string title, string message, string subTitle, ConsoleColor consoleColor)
        {
            Console.ForegroundColor = consoleColor;
            string dateNowTxt = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
            Console.WriteLine(string.IsNullOrEmpty(subTitle) ? $"[{dateNowTxt}]{title}:{message}" : $"[{dateNowTxt}]{title}[{subTitle}]:{message}");
            Console.ForegroundColor = ConsoleColor.White;
        }
        /// <summary>
        /// 写入控制台
        /// </summary>
        /// <param name="message"></param>
        /// <param name="subTitle"></param>
        /// <param name="consoleColor"></param>
        public static void ServerWrite(string message, string subTitle = null, ConsoleColor consoleColor = ConsoleColor.White)
        {
            Write("Server", message, subTitle, consoleColor);
        }
        /// <summary>
        /// 写入控制台
        /// </summary>
        /// <param name="message"></param>
        /// <param name="subTitle"></param>
        /// <param name="consoleColor"></param>
        public static void ServerWriteLine(string message, string subTitle = null, ConsoleColor consoleColor = ConsoleColor.White)
        {
            WriteLine("Server", message, subTitle, consoleColor);
        }
        /// <summary>
        /// 写入错误
        /// </summary>
        /// <param name="exception"></param>
        public static void ServerWriteError(Exception exception)
        {
            ServerWriteLine(GetErrorMessage(exception), "错误", ConsoleColor.Red);
        }
        #region 私有方法
        /// <summary>
        /// 递归获取异常的完整错误信息，包括所有内部异常详情
        /// </summary>
        /// <param name="exception">需要处理的异常对象</param>
        /// <returns>包含完整错误信息的字符串（包含消息和堆栈跟踪）</returns>
        private static string GetErrorMessage(Exception exception)
        {
            // 先获取当前异常的错误消息
            string message = $"{exception.Message}";

            // 如果存在堆栈跟踪信息，则添加到消息中
            if (!string.IsNullOrEmpty(exception.StackTrace))
                message += $"\r\n{exception.StackTrace}";

            // 处理聚合异常（AggregateException）的特殊情况
            // 聚合异常通常包含多个内部异常（如并行操作中的多个异常）
            if (exception is AggregateException aggregateException)
            {
                // 遍历聚合异常中的所有内部异常
                foreach (Exception innerException in aggregateException.InnerExceptions)
                {
                    Exception ex = innerException;
                    // 循环获取当前内部异常及其嵌套的内部异常信息
                    do
                    {
                        // 递归调用当前方法，获取内部异常的完整信息
                        // 注意：原代码此处可能存在笔误，应该传入ex而不是exception
                        message += $"\r\n{GetErrorMessage(ex)}";
                        // 移动到下一层内部异常
                        ex = ex.InnerException;
                    } while (ex != null); // 直到没有更多内部异常
                }
            }
            else
            {
                // 处理普通异常的内部异常（非聚合异常）
                // 循环获取所有嵌套的内部异常
                while (exception.InnerException != null)
                {
                    // 移动到内部异常
                    exception = exception.InnerException;
                    // 递归调用当前方法，获取内部异常的完整信息
                    message += $"\r\n{GetErrorMessage(exception)}";
                }
            }

            // 返回组装好的完整错误信息
            return message;
        }
        #endregion
    }
}
